package com.bdgls.unicode;


import com.google.gson.Gson;

/**
 * Created by yibo on 2016-5-6.
 */
public class UnicodeConverter {

    public static byte[] unicode2utf8(int src) throws Exception {

        byte[] result = null;
        if (src >= 0x0 && src <= 0x7f) {
            result = getBytes_1Byte_enhance(src);
        } else if (src >= 0x80 && src <= 0x7ff) {
            result = getBytes_2Byte_enhance(src);
        } else if (src >= 0x800 && src <= 0xffff) {
            result = getBytes_3Byte_enhance(src);
        } else if (src >= 0x10000 && src <= 0x10FFFF) {
            result = getBytes_4Byte_enhance(src);
        }

        return result;
    }

    private static byte[] getBytes_4Byte_enhance(int src) throws Exception {

        int b0 = 0b11110000;
        int b1 = 0b10000000;
        int b2 = 0b10000000;
        int b3 = 0b10000000;

        int tail = src & 0b111111;
        b3 = b3 | tail;
        src = src >> 6;

        tail = src & 0b111111;
        b2 = b2 | tail;
        src = src >> 6;

        tail = src & 0b111111;
        b1 = b1 | tail;
        src = src >> 6;

        tail = src & 0b111;
        b0 = b0 | tail;

        byte[] buff = new byte[4];
        buff[0] = convert2ByteFromInt(b0);
        buff[1] = convert2ByteFromInt(b1);
        buff[2] = convert2ByteFromInt(b2);
        buff[3] = convert2ByteFromInt(b3);
        return buff;
    }

    private static byte[] getBytes_3Byte_enhance(int src) throws Exception {

        int b0 = 0b11100000;
        int b1 = 0b10000000;
        int b2 = 0b10000000;

        int tail = src & 0b111111;
        b2 = b2 | tail;
        src = src >> 6;

        tail = src & 0b111111;
        b1 = b1 | tail;
        src = src >> 6;

        tail = src & 0b1111;
        b0 = b0 | tail;

        byte[] buff = new byte[3];
        buff[0] = convert2ByteFromInt(b0);
        buff[1] = convert2ByteFromInt(b1);
        buff[2] = convert2ByteFromInt(b2);
        return buff;
    }

    private static byte[] getBytes_2Byte_enhance(int src) throws Exception {

        int b0 = 0b11000000;
        int b1 = 0b10000000;

        int tail = src & 0b111111;
        b1 = b1 | tail;
        src = src >> 6;

        tail = src & 0b11111;
        b0 = b0 | tail;

        byte[] buff = new byte[2];
        buff[0] = convert2ByteFromInt(b0);
        buff[1] = convert2ByteFromInt(b1);
        return buff;
    }

    private static byte[] getBytes_1Byte_enhance(int src) throws Exception {

        int b0 = 0b00000000;
        int tail = src & 0b1111111;
        b0 = b0 | tail;
        byte[] buff = new byte[1];
        buff[0] = convert2ByteFromInt(b0);
        return buff;
    }

    public static byte convert2ByteFromInt(int b) {

        byte result = 0;
        if (((b >> 7) & 0b1) == 0b1) {

            int right = b & 0b1111111;
            right = ~right;
            right = right & 0b01111111;
            right = right + 1;
            result = (byte) (-1 * right);
        } else {
            result = (byte) (b & 0xff);
        }

        return result;
    }


    public static String unicodeStr2Utf8_Jsonbuff(String src) throws Exception {


        int intVal = parseHexStr(src);
        byte[] buff1 = unicode2utf8(intVal);
        Gson gson = new Gson();
        String result = gson.toJson(buff1);
        return result;

    }

    /**
     * 最多4字节的
     * @param hexStr
     * @return
     * @throws Exception
     */
    public static int parseHexStr(String hexStr) throws Exception {

        hexStr = hexStr.toLowerCase().trim();
        if (!hexStr.substring(0, 2).equals("0x")) {
            throw new Exception("bad format");
        }

        String line = hexStr.substring(2, hexStr.length());

        if (line.length() > 8) {
            throw new Exception("bad format1");
        }

        int left = 8 - line.length();
        String pad = "";
        for (int i = 0; i < left; i++) {
            pad += "0";
        }

        line = pad + line;

        String item0 = line.substring(0, 2);
        String item1 = line.substring(2, 4);
        String item2 = line.substring(4, 6);
        String item3 = line.substring(6, 8);
        int b0 = ByteHexStr2Int(item0);
        int b1 = ByteHexStr2Int(item1);
        int b2 = ByteHexStr2Int(item2);
        int b3 = ByteHexStr2Int(item3);

        int temp = b0 << 24 | b1 << 16 | b2 << 8 | b3 << 0;

        return temp;
    }

    public static int ByteHexStr2Int(String hexStr) throws Exception {

        if (hexStr.length() != 2) {
            throw new Exception("bad format");
        }

        hexStr = hexStr.toUpperCase();
        int temp = 0;

        char c0 = hexStr.charAt(0);
        if (c0 >= 48 && c0 <= 57) {
            int val0 = (c0 - 48) * 16;
            temp += val0;
        } else if (c0 >= 65 && c0 <= 70) {
            int val0 = (c0 - 65 + 10) * 16;
            temp += val0;
        } else {
            throw new Exception("bad format 3");
        }

        char c1 = hexStr.charAt(1);
        if (c1 >= 48 && c1 <= 57) {
            int val1 = (c1 - 48) * 1;
            temp += val1;
        } else if (c1 >= 65 && c1 <= 70) {
            int val1 = (c1 - 65 + 10) * 1;
            temp += val1;
        } else {
            throw new Exception("bad format 3 2");
        }

        return temp;
    }

}
